#ifndef CKTINFO_H
#define CKTINFO_H

#include "base/aig.h"
#include "lit_union.h"

typedef unsigned level_t;
typedef uint8_t    mark_t;

//___ Ckt Info ________________________________________________________________
// 
// Management the information in the algorithms 
// Information include equivalance relation ( use for merge node )
//                     general mark
//                     fanout reference count 
//                     require time and arriaval time 
//                     level and reverse level ( arrival time and require time )
//                   
//=============================================================================

class CktInfo : public LitUnion , public StrashAIG
{
   void factor_topological_traversal( vec<unsigned> & ord ); //traversing, help for factor
	unsigned remove_cyclic( unsigned , unsigned );

   void reset_level();                                //init,       reset level
   void rlevel_recover( unsigned n );                 //update,     reverse level updating

   //*** Circuit Information ****
   public:
      void create_focnt();                               //init,       fanout count

      vec<unsigned>    _tmp_cone;// common usage

      vec<mark_t>      _mrk;
      vec<unsigned>    _focnt;
      vec<level_t>     _level;
      vec<level_t>     _rlevel;
      unsigned         _max_level;

   //*** Functions 
      CktInfo() : LitUnion( (StrashAIG & )(*this) ) {};
      ~CktInfo(){}

      void init();
      void factor(StrashAIG & c );
      void validation();
   
      //--- Traverse functions 
      void replace( unsigned , unsigned , unsigned focnt);  //updating, 
      void resume( unsigned * cone , unsigned s );          //updating

      unsigned get_cone( unsigned n , vec<unsigned> & cone);
      void     rm_cone ( unsigned n );
      unsigned get_freeCone( unsigned n , vec<unsigned> & cone);

      //--- Construction and asking 
      AigLit build_blAND( AigLit * , unsigned s );   //build the "AND" by level 
      bool   todo(unsigned idx );                      //querry the node should be reconstruct
      
   //*** Query Functions 
      unsigned eqInIdx( unsigned i , unsigned j )const{ return eqIdx( var( data[i].fanin[j]) );}
      AigLit   eqIn(    unsigned i , unsigned j )const{ return eq( data[i].fanin[j] );}
      unsigned lvl(unsigned);
      void update_level( unsigned ); // use in cnf2aig // not consider eq

   //*** accept condition 
      bool     direct_accept( unsigned t , unsigned p ){return t!=p;}
      bool     level_accept( unsigned t , unsigned p ){return (t!=p) && ( (lvl(p)+_rlevel[t])<=_max_level);}
      bool     accept( unsigned t , unsigned p ){return LEVEL_CONSIDER?level_accept(t,p):direct_accept(t,p);}
   
   public://PARAMETER
      static int LEVEL_CONSIDER; // replace consider : 0 heuistic level , 1 consider level , 2 arrival recover
};

#endif
